﻿using Sidvall.Serialization;

namespace Sidvall.Business
{
    public static class ValidationManager
    {
        #region GetDateTimeWithSpecifiedKind

        public static System.DateTime? GetDateTimeWithSpecifiedKind(object value, System.DateTimeKind kind)
        {
            return GetDateTimeWithSpecifiedKind(value.ToNullableDateTime(), kind);
        }
        public static System.DateTime? GetDateTimeWithSpecifiedKind(System.DateTime? value, System.DateTimeKind kind)
        {
            if (value == null)
                return null;
            else
                return GetDateTimeWithSpecifiedKind(value.Value, kind);
        }
        public static System.DateTime GetDateTimeWithSpecifiedKind(System.DateTime value, System.DateTimeKind kind)
        {
            return System.DateTime.SpecifyKind(value, kind);
        }

        #endregion

        #region GetValidByte

        public static byte? GetValidByte(object value, byte? minValue, byte? maxValue)
        {
            return GetValidByte(value.ToNullableByte(), minValue, maxValue);
        }
        public static byte? GetValidByte(byte? value, byte? minValue, byte? maxValue)
        {
            if (value == null)
                return null;
            return GetValidByte(value.Value, minValue, maxValue);
        }
        public static byte GetValidByte(byte value, byte? minValue, byte? maxValue)
        {
            if (minValue != null)
            {
                if (value < minValue.Value)
                    value = minValue.Value;
            }
            if (maxValue != null)
            {
                if (value > maxValue.Value)
                    value = maxValue.Value;
            }
            return value;
        }

        #endregion
        #region GetValidDate

        public static System.DateTime? GetValidDate(object value)
        {
            return GetValidDate(value.ToNullableDateTime());
        }
        public static System.DateTime? GetValidDate(System.DateTime? value)
        {
            if (value == null)
                return null;
            else
                return GetValidDate(value.Value);
        }
        public static System.DateTime GetValidDate(System.DateTime value)
        {
            return value.Date;
        }

        #endregion
        #region GetValidDateTime

        public static System.DateTime? GetValidDateTime(object value)
        {
            return GetValidDateTime(value, System.DateTimeKind.Local);
        }
        public static System.DateTime? GetValidDateTime(System.DateTime? value)
        {
            return GetValidDateTime(value, System.DateTimeKind.Local);
        }
        public static System.DateTime GetValidDateTime(System.DateTime value)
        {
            return GetValidDateTime(value, System.DateTimeKind.Local);
        }
        public static System.DateTime? GetValidDateTime(object value, System.DateTimeKind timeType)
        {
            return GetValidDateTime(value.ToNullableDateTime(), timeType);
        }
        public static System.DateTime? GetValidDateTime(System.DateTime? value, System.DateTimeKind timeType)
        {
            if (value == null)
                return null;
            else
                return GetValidDateTime(value.Value, timeType);
        }
        public static System.DateTime GetValidDateTime(System.DateTime value, System.DateTimeKind timeType)
        {
            switch (timeType)
            {
                case System.DateTimeKind.Local:
                    return value.ToLocalTime();
                case System.DateTimeKind.Utc:
                    return value.ToUniversalTime();
                default:
                    return value;
            }
        }
        public static System.DateTime? GetValidDateTime(object value, System.DateTimeKind timeType, System.DateTimeKind unspecifiedTimeType)
        {
            return GetValidDateTime(value.ToNullableDateTime(), timeType, unspecifiedTimeType);
        }
        public static System.DateTime? GetValidDateTime(System.DateTime? value, System.DateTimeKind timeType, System.DateTimeKind unspecifiedTimeType)
        {
            if (value == null)
                return null;
            else
                return GetValidDateTime(value.Value, timeType, unspecifiedTimeType);
        }
        public static System.DateTime GetValidDateTime(System.DateTime value, System.DateTimeKind timeType, System.DateTimeKind unspecifiedTimeType)
        {
            if (value.Kind == System.DateTimeKind.Unspecified)
                value = GetDateTimeWithSpecifiedKind(value, unspecifiedTimeType);
            return GetValidDateTime(value, timeType);
        }

        #endregion
        #region GetValidDecimal

        public static decimal? GetValidDecimal(object value, decimal? minValue, decimal? maxValue, int? maxDecimalCount)
        {
            return GetValidDecimal(value.ToNullableDecimal(), minValue, maxValue, maxDecimalCount);
        }
        public static decimal? GetValidDecimal(decimal? value, decimal? minValue, decimal? maxValue, int? maxDecimalCount)
        {
            if (value == null)
                return null;
            return GetValidDecimal(value.Value, minValue, maxValue, maxDecimalCount);
        }
        public static decimal GetValidDecimal(decimal value, decimal? minValue, decimal? maxValue, int? maxDecimalCount)
        {
            if (maxDecimalCount != null)
                value = System.Math.Round(value, maxDecimalCount.Value, System.MidpointRounding.AwayFromZero);
            if (minValue != null)
            {
                if (value < minValue.Value)
                    value = minValue.Value;
            }
            if (maxValue != null)
            {
                if (value > maxValue.Value)
                    value = maxValue.Value;
            }
            return value;
        }

        #endregion
        #region GetValidDouble

        public static double? GetValidDouble(object value, double? minValue, double? maxValue, int? maxDecimalCount)
        {
            return GetValidDouble(value.ToNullableDouble(), minValue, maxValue, maxDecimalCount);
        }
        public static double? GetValidDouble(double? value, double? minValue, double? maxValue, int? maxDecimalCount)
        {
            if (value == null)
                return null;
            return GetValidDouble(value.Value, minValue, maxValue, maxDecimalCount);
        }
        public static double GetValidDouble(double value, double? minValue, double? maxValue, int? maxDecimalCount)
        {
            if (maxDecimalCount != null)
                value = System.Math.Round(value, maxDecimalCount.Value, System.MidpointRounding.AwayFromZero);
            if (minValue != null)
            {
                if (value < minValue.Value)
                    value = minValue.Value;
            }
            if (maxValue != null)
            {
                if (value > maxValue.Value)
                    value = maxValue.Value;
            }
            return value;
        }

        #endregion
        #region GetValidInt16

        public static short? GetValidInt16(object value, short? minValue, short? maxValue)
        {
            return GetValidInt16(value.ToNullableInt16(), minValue, maxValue);
        }
        public static short? GetValidInt16(short? value, short? minValue, short? maxValue)
        {
            if (value == null)
                return null;
            return GetValidInt16(value.Value, minValue, maxValue);
        }
        public static short GetValidInt16(short value, short? minValue, short? maxValue)
        {
            if (minValue != null)
            {
                if (value < minValue.Value)
                    value = minValue.Value;
            }
            if (maxValue != null)
            {
                if (value > maxValue.Value)
                    value = maxValue.Value;
            }
            return value;
        }

        #endregion
        #region GetValidInt32

        public static int? GetValidInt32(object value, int? minValue, int? maxValue)
        {
            return GetValidInt32(value.ToNullableInt32(), minValue, maxValue);
        }
        public static int? GetValidInt32(int? value, int? minValue, int? maxValue)
        {
            if (value == null)
                return null;
            return GetValidInt32(value.Value, minValue, maxValue);
        }
        public static int GetValidInt32(int value, int? minValue, int? maxValue)
        {
            if (minValue != null)
            {
                if (value < minValue.Value)
                    value = minValue.Value;
            }
            if (maxValue != null)
            {
                if (value > maxValue.Value)
                    value = maxValue.Value;
            }
            return value;
        }

        #endregion
        #region GetValidInt64

        public static long? GetValidInt64(object value, long? minValue, long? maxValue)
        {
            return GetValidInt64(value.ToNullableInt64(), minValue, maxValue);
        }
        public static long? GetValidInt64(long? value, long? minValue, long? maxValue)
        {
            if (value == null)
                return null;
            return GetValidInt64(value.Value, minValue, maxValue);
        }
        public static long GetValidInt64(long value, long? minValue, long? maxValue)
        {
            if (minValue != null)
            {
                if (value < minValue.Value)
                    value = minValue.Value;
            }
            if (maxValue != null)
            {
                if (value > maxValue.Value)
                    value = maxValue.Value;
            }
            return value;
        }

        #endregion
        #region GetValidUniversalDateTime

        public static System.DateTime? GetValidUniversalDateTime(object value)
        {
            return GetValidDateTime(value, System.DateTimeKind.Utc);
        }
        public static System.DateTime? GetValidUniversalDateTime(System.DateTime? value)
        {
            return GetValidDateTime(value, System.DateTimeKind.Utc);
        }
        public static System.DateTime GetValidUniversalDateTime(System.DateTime value)
        {
            return GetValidDateTime(value, System.DateTimeKind.Utc);
        }
        public static System.DateTime? GetValidUniversalDateTime(object value, System.DateTimeKind unspecifiedTimeType)
        {
            return GetValidDateTime(value, System.DateTimeKind.Utc, unspecifiedTimeType);
        }
        public static System.DateTime? GetValidUniversalDateTime(System.DateTime? value, System.DateTimeKind unspecifiedTimeType)
        {
            return GetValidDateTime(value, System.DateTimeKind.Utc, unspecifiedTimeType);
        }
        public static System.DateTime GetValidUniversalDateTime(System.DateTime value, System.DateTimeKind unspecifiedTimeType)
        {
            return GetValidDateTime(value, System.DateTimeKind.Utc, unspecifiedTimeType);
        }

        #endregion
        #region GetValidString

        public static string GetValidString(object value, bool isNullable, int? maxLength)
        {
            return GetValidString(value, isNullable, maxLength, true);
        }
        public static string GetValidString(string value, bool isNullable, int? maxLength)
        {
            return GetValidString(value, isNullable, maxLength, true);
        }
        public static string GetValidString(object value, bool isNullable, int? maxLength, bool trim)
        {
            if (value != null)
                return GetValidString(value.ToString(), isNullable, maxLength, trim);
            else
                return GetValidString((string)null, isNullable, maxLength, trim);
        }
        public static string GetValidString(string value, bool isNullable, int? maxLength, bool trim)
        {
            if (value == null)
            {
                if (isNullable)
                    return null;
                else
                    return string.Empty;
            }
            else
            {
                if (trim)
                    value = value.Trim();
                if ((maxLength != null) && (value.Length > maxLength.Value))
                    value = value.Substring(0, maxLength.Value);
                return value;
            }
        }

        #endregion
        #region IsEqual

        public static bool IsEqual(object value1, object value2)
        {
            if (value1 == null)
            {
                if (value2 == null)
                    return true;
                else
                    return false;
            }
            if (value2 == null)
                return false;
            return value1.Equals(value2);
        }

        #endregion
    }
}
